package com.magenta.maxoptra.geocoding.google;


import static com.magenta.commons.datetime.DateTimeConstants.MSECS_IN_DAY;

import java.util.HashMap;
import java.util.Map;

/*
* Project: MaxOptRA v1.2
* User: Ivan Usalko
* Date: 22.09.2009 20:58:11
*
* Copyright (c) 1999-2009 Magenta Corporation Ltd. All Rights Reserved.
* Magenta Technology proprietary and confidential.
* Use is subject to license terms.
*/
class TenThousandPerDay {
    static final Map<String, StatisticEntry> stat;

    static {
        stat = new HashMap<String, StatisticEntry>(30);
    }

    private final StatisticEntry entry;

    TenThousandPerDay(String key) {
        StatisticEntry entry = stat.get(key);
        if (entry == null) {
            entry = new StatisticEntry();
            stat.put(key, entry);
        }
        this.entry =entry; 
    }

    synchronized boolean isBlockPossible() {
        long time = currentTime();
        long delta = time - entry.lastRequestTime;
        long delta0 = entry.lastLimitOverheadTime > 0 ? time - entry.lastLimitOverheadTime : 0L;
        if (delta >= MSECS_IN_DAY) {
            entry.requestCount = 0;
        }
        else if (delta0 >= MSECS_IN_DAY){
            int lossProfits = (int) ((delta * 10000) / MSECS_IN_DAY);
            entry.requestCount -= lossProfits;
        }
        else {
            int constrRelax = (int) ((delta0 * 10000) / MSECS_IN_DAY);
            entry.requestCount -= constrRelax;
        }

        return entry.requestCount+1 > 10000 || entry.requestCount++ > 10001 || //mod 10000 addition
            (entry.lastRequestTime = time) > time + 1 || //last real request update
            (entry.requestCount == 10000? (entry.lastLimitOverheadTime = time) > time + 1 : time > currentTime()); //last overhead update        
    }

    long currentTime() {
        return System.currentTimeMillis();
    }


    private class StatisticEntry {
        int requestCount;
        long lastRequestTime;
        long lastLimitOverheadTime;
    }
}
